using System;
using System.Collections;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using Microsoft.IdentityModel.Tokens;
using netCoreStudy.Auth;
using netCoreStudy.Entities;
using Newtonsoft.Json;

namespace netCoreStudy.Helper
{
	/// <summary>
	/// jwt 帮助类
	/// </summary>
	public class JwtHelper
	{
		/// <summary>
		/// 生成token
		/// </summary>
		/// <returns></returns>
		public static string GetToken(User user, PermissionRequirement requirement)
		{
			// 获取 该用户 的 role 列表(int[])
			long[] roleNames = user.UserRoles.Select(x => x.Role.Id).ToArray();
			// 设置 一个claims 
			double expirationTotalSeconds = requirement.Expiration.TotalSeconds;
			List<Claim> claims = new List<Claim>
			{
				// 加入 用户名
				new Claim(ClaimTypes.Name, user.Name),
				// 加入 用户 id 
				new Claim(JwtRegisteredClaimNames.Jti, user.Id.ToString()),
				// 加入 过期时间  100秒后过期 (存的时未来100秒的时间戳 类似  1601213359 这样的秒时间戳(2020/9/27 21:30:09) )
				new Claim(JwtRegisteredClaimNames.Exp,
					new DateTimeOffset(DateTime.Now.AddSeconds(expirationTotalSeconds)).ToUnixTimeSeconds().ToString())
			};
			// 加入 用户 的角色 (遍历)
			foreach (long roleId in roleNames)
			{
				claims.Add(new Claim(ClaimTypes.Role, roleId.ToString()));
			}

			//  构造 token
			JwtSecurityToken jwtToken = new JwtSecurityToken(
				issuer: requirement.Issuer,
				audience: requirement.Audience,
				claims: claims,
				notBefore: DateTime.Now,
				expires: DateTime.Now.Add(requirement.Expiration),
				signingCredentials: requirement.SigningCredentials);

			//  将 token 写成 string 
			string token = new JwtSecurityTokenHandler().WriteToken(jwtToken);
			return token;
		}


		/// <summary>
		/// 解析
		/// </summary>
		/// <param name="jwtStr"></param>
		/// <returns></returns>
		public static TokenModelJwt SerializeJwt(string jwtStr)
		{
			var jwtHandler = new JwtSecurityTokenHandler();
			TokenModelJwt tokenModelJwt = new TokenModelJwt();

			// token校验
			if (jwtStr.IsNotEmptyOrNull() && jwtHandler.CanReadToken(jwtStr))
			{
				JwtSecurityToken jwtToken = jwtHandler.ReadJwtToken(jwtStr);

				object role;


				jwtToken.Payload.TryGetValue(ClaimTypes.Role, out role);

				Console.WriteLine(role.ToString());
				tokenModelJwt = new TokenModelJwt
				{
					Uid = (jwtToken.Id).ObjToInt(),
					Role = role != null ? role.ObjToString() : "",
				};
			}

			return tokenModelJwt;
		}

		/// <summary>
		/// 解析token
		/// </summary>
		/// <returns>返回 用户 id 和 角色 列表 </returns>
		public static (long id, List<string> role) ParseJwt(string jwtToken)
		{
			JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
			JwtSecurityToken securityToken = handler.ReadJwtToken(jwtToken);
			object role;
			securityToken.Payload.TryGetValue(ClaimTypes.Role, out role);
			Console.WriteLine(role);
			IEnumerable list = role as IEnumerable;
			List<string> list1 = new List<string>();
			foreach (var o in list)
			{
				list1.Add(o.ToString());
			}

			Console.WriteLine(JsonConvert.SerializeObject(list1));
			Console.WriteLine(securityToken.Id);
			return (long.Parse(securityToken.Id), list1);
		}
	}
}